﻿// Copyright (c) Alexandre Mutel. All rights reserved.
// Licensed under the BSD-Clause 2 license.
// See license.txt file in the project root for full license information.

using System;
using System.Globalization;
using CppAst.CodeGen.Common;
using Zio;

namespace CppAst.CodeGen.CSharp
{
    public class CSharpGeneratedFile : CSharpElement, ICSharpContainer
    {
        public const string FileGeneratedByKey = "FileGeneratedBy";

        public CSharpGeneratedFile(UPath filePath)
        {
            if (filePath.IsNull || filePath.IsEmpty) throw new ArgumentNullException(nameof(filePath));
            FilePath = filePath;
            Members = new CSharpContainerList<CSharpElement>(this);
            EmitAutoGenerated = true;
        }

        /// <inheritdoc />
        ICSharpContainer ICSharpContainer.Parent => Parent as ICSharpContainer;

        public UPath FilePath { get; set; }

        public bool EmitAutoGenerated { get; set; }

        /// <inheritdoc />
        public CSharpContainerList<CSharpElement> Members { get; }

        /// <inheritdoc />
        public void ValidateMember(CSharpElement element)
        {
            if (element is CSharpCompilation || element is CSharpGeneratedFile)
            {
                throw new ArgumentException($"Cannot add a {element.GetType().Name} to members of a {nameof(CSharpGeneratedFile)}");
            }
        }

        /// <inheritdoc />
        public override void DumpTo(CodeWriter writer)
        {
            if (writer.Mode == CodeWriterMode.Full)
            {
                // In full mode we actually write to the disk
                writer.PushFileOutput(FilePath);
                try
                {
                    if (EmitAutoGenerated)
                    {
                        writer.WriteLine($@"//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by {writer.Options[FileGeneratedByKey] ?? "a tool"}.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
");
                    }

                    this.DumpMembersTo(writer);
                }
                finally
                {
                    writer.PopOutput();
                }
            }
            else
            {
                writer.Write("File: ").Write(FilePath.FullName).Write(" Members = ").Write(Members.Count.ToString(CultureInfo.InvariantCulture));
            }
        }
    }
}